<?php

namespace Xiaoc\Api;

use PhalApi\Api;

/**
 * Xiaoc购物车操作
 *
 * @author: zhy <zhy302813@163.com> 2017-8-19
 */
class Cart extends Common {

    public function getRules() {
        return array(
            'addcart' => array(
                'goods_id' => array('name' => 'goods_id', 'type' => 'int', 'require' => true, 'desc' => '商品ID'),
                'token' => array('name' => 'token', 'require' => true, 'desc' => '用户Token'),
                'number' => array('name' => 'number', 'require' => true, 'default' => 1, 'desc' => '购买数量'),
                'ru_id' => array('name' => 'ru_id', 'type' => 'int', 'require' => true, 'default' => 0, 'desc' => '店铺ID'),
                'spec' => array('name' => 'spec', 'type' => 'array', 'format' => 'explode', 'separator' => ',', 'desc' => '商品规格(多个规格ID以,分割)'),
                'is_crowd' => array('name' => 'is_crowd', 'require' => true, 'default' => 0, 'desc' => '是否是众筹商品（1是）')
            ),
            'cartlist' => array(
                'token' => array('name' => 'token', 'require' => true, 'desc' => '用户Token')
            ),
            'updatecart' => array(
                'rec_id' => array('name' => 'rec_id', 'require' => true, 'desc' => '购物车ID'),
                'goods_number' => array('name' => 'goods_number', 'require' => true, 'desc' => '商品数量')
            ),
            'delcart' => array(
                'rec_id' => array('name' => 'rec_id', 'type' => 'array', 'format' => 'explode', 'separator' => ',', 'desc' => '购物车ID(多个ID以,分割)')
            )
        );
    }

    /**
     * 购物车操作
     * @desc 添加购物车
     * @return int rec_id 购物车ID
     */
    public function addcart() {

        $prefix = \PhalApi\DI()->config->get('dbs.tables.__default__.prefix');

        $userinfo = $this->check_login($this->token);

        $goods_id = $this->goods_id;
        if (!is_numeric($goods_id) || (intval($goods_id) <= 0)) {
            $this->api_error_msg('参数错误！');
        }
        $store_id = intval($this->ru_id);

        $goods_number = intval($this->number);
        if (!is_numeric($goods_number) || ($goods_number <= 0)) {
            $this->api_error_msg('参数错误！');
        } else {
            $addcart = $this->addto_cart($goods_id, $goods_number, $this->spec, $userinfo['user_id'], $store_id,$this->is_crowd);
            if ($addcart) {
                return $addcart;
            }
        }
        $this->api_error_msg('添加失败！');
    }

    private function addto_cart($goods_id, $num = 1, $spec = array(), $user_id, $store_id = 0,$is_crowd = 0) {
        //查出该商品
        $goods = \PhalApi\DI()
                    ->notorm
                    ->goods
                    ->select('goods_number,goods_sn,goods_id,goods_name,shop_price,market_price,goods_brief,goods_thumb,goods_product_tag,is_real,model_attr,user_id as ru_id,is_shipping,shipping_fee,extension_code')
                    ->where(array('review_status > ?' => 2, 'goods_number > ?' => 0,'goods_id'=>$goods_id,'is_delete'=>0,'is_on_sale'=>1))
                    ->fetchOne();
        if (empty($goods)) {
            return false;
        }
        //如果有商户id
        if (0 < $store_id ) {
            $goodsnumber = \PhalApi\DI()
                        ->notorm
                        ->store_goods
                        ->select('goods_number')
                        ->where(array('goods_id'=>$goods_id,'store_id'=>$store_id))
                        ->fetchOne();
            $goods['goods_number'] = $goodsnumber['goods_number'];
        }
        //没有商户则直接插products
        $where['goods_id'] = $goods_id;
        if (0 < $store_id) {
            $table_products = 'store_products';
            $where['store_id'] = $store_id;
        } else {
            $table_products = 'products';
        }
        //查出一条属于该goods_id的产品
        $prod = \PhalApi\DI()
                        ->notorm
                        ->$table_products
                        ->where($where)
                        ->fetchOne();
        //如果有规格id,查出这个产品的信息
        if ($this->is_spec($spec) && !empty($prod)) {
            $product_info = $this->get_products_info($goods_id, $spec , $store_id);
        }
        //如果这个产品为空
        if (empty($product_info)) {
            $product_info = array('product_number' => 0, 'product_id' => 0);
        }
        //读取系统配置
        if ($this->getConfig('use_storage') == 1) {
            $is_product = 0;
            if ($this->is_spec($spec) && !empty($prod)) {
                if (!empty($spec)) {
                    if ($product_info['product_number'] < $num) {
                        $this->api_error_msg('库存不足！');
                        return false;
                    }
                }
            } else {
                $is_product = 1;
            }
            
            if ($is_product == 1) {
                if ($goods['goods_number'] < $num) {
                    $this->api_error_msg('库存不足！');
                    return false;
                }
            }
        }

        if ($this->getConfig('add_shop_price') == 1) {
            $add_tocart = 1;
        } else {
            $add_tocart = 0;
        }

        $spec_price = $this->spec_price($spec, $goods_id);
        $goods_price = $spec_price+$goods['shop_price'];
        
        if ($is_crowd == 1) {
            $prefix = \PhalApi\DI()->config->get('dbs.tables.__default__.prefix');
            $crowd = \PhalApi\DI()
                    ->notorm
                    ->goods_activity
                    ->select('act_id,ext_info,goods_id,start_time,end_time')
                    ->where(array('review_status' => 3, 'start_time < ?' => gmtime(), 'end_time > ?' => gmtime(), 'act_type' => 1, 'goods_id' => $goods_id))
                    ->order('act_id desc')
                    ->fetchOne();

            $sql = "select SUM(og.goods_number) as goods_number from "
                    . $prefix . "order_info as oi left join "
                    . $prefix . "order_goods as og on oi.order_id = og.order_id "
                    . "where og.goods_id = " . $crowd['goods_id'] . "  and oi.extension_code ='group_buy' and oi.add_time > " . $crowd['start_time'] . " and oi.add_time < " . $crowd['end_time']
                    . " group by og.goods_id";
            $rows = \PhalApi\DI()->notorm->order_info->queryAll($sql, array());
            $join = isset($rows[0]['goods_number']) ? $rows[0]['goods_number'] : 0;
            
            $crowdprice = unserialize($crowd['ext_info']);
            $pricelist = $crowdprice['price_ladder'];
            foreach($pricelist as $vo){
                $amount = $vo['amount'];
                if($join > $amount){
                    $upto[] = $vo['price'];
                }
            }
            if(@is_array($upto)){
                @sort($upto);
            }
            $goods_price = @$upto[0]>0 ? @$upto[0]: $goods_price;
        }
        
        $goods['market_price'] += $spec_price;
        
        $goods_attr = $this->get_goods_attr_info($spec, 'pice');
        $goods_attr_id = '';
        if (!empty($spec)) {
            $goods_attr_id = join(',', $spec);
        }
        $parent = array(
            'user_id' => $user_id, 
            'session_id' => '',
            'goods_id' => $goods_id, 
            'goods_sn' => addslashes($goods['goods_sn']),
            'product_id' => $product_info['product_id'],
            'goods_name' => addslashes($goods['goods_name']), 
            'market_price' => $goods['market_price'], 
            'goods_attr' => addslashes($goods_attr),
            'goods_attr_id' => $goods_attr_id, 
            'is_real' => $goods['is_real'], 
            'model_attr' => $goods['model_attr'],
            'warehouse_id' => 0, 
            'area_id' => 0, 
            'ru_id' => $goods['ru_id'], 
            'extension_code' => $goods['extension_code'],
            'is_gift' => 0,
            'is_shipping' => $goods['is_shipping'],
            'shipping_fee' => $goods['shipping_fee'],
            'rec_type' => $is_crowd,
            'add_time' => gmtime(),
            'store_id' => $store_id
        );

        $parent['goods_price'] = $goods_price;
        $parent['goods_number'] = $num;
        $parent['parent_id'] = 0;
        $cart = \PhalApi\DI()->notorm->cart->select('rec_id,goods_number')->where(array('user_id'=>$user_id,'goods_id'=>$goods_id,'product_id'=>$product_info['product_id'],'goods_attr_id'=>$goods_attr_id))->fetchOne();
        if(isset($cart['rec_id']) && $cart['rec_id'] > 0){
            $act = \PhalApi\DI()->notorm->cart->where('rec_id',$cart['rec_id'])->update(array('goods_number'=>$cart['goods_number']+$num));
            $id = $cart['rec_id'];
        }else{
            \PhalApi\DI()->notorm->cart->insert($parent);
            $act = \PhalApi\DI()->notorm->cart->insert_id();
            $id = $act;
        }
        
        if($act){
            return $id;
        }
        return false;
    }
    private function is_spec($goods_attr_id_array, $sort = 'asc') {
        
        $prefix = \PhalApi\DI()->config->get('dbs.tables.__default__.prefix');
        
        if (empty($goods_attr_id_array)) {
            return $goods_attr_id_array;
        }
        $sql = "select a.attr_type, v.attr_value, v.goods_attr_id from " . 
                $prefix."attribute as a left join " .$prefix."goods_attr as v on v.attr_id = a.attr_id and a.attr_type = 1 where v.goods_attr_id " .
                db_create_in($goods_attr_id_array) . " order by a.attr_id " . $sort;
        $row = \PhalApi\DI()->notorm->attribute->queryAll($sql, array());
        $return_arr = array();

        foreach ($row as $value) {
            $return_arr['sort'][] = $value['goods_attr_id'];
            $return_arr['row'][$value['goods_attr_id']] = $value;
        }
        if (!empty($return_arr)) {
            return true;
        } else {
            return false;
        }
    }
    private function get_products_info($goods_id, $spec_goods_attr_id, $store_id = 0) {

        $return_array = array();
        if (empty($spec_goods_attr_id) || !is_array($spec_goods_attr_id) || empty($goods_id)) {
            return $return_array;
        }

        $goods_attr_array = $this->sort_goods_attr_id_array($spec_goods_attr_id);

        if (isset($goods_attr_array['sort'])) {
            $goods_attr = implode('|', $goods_attr_array['sort']);
            $where['goods_id'] = $goods_id;
            $where['goods_attr'] = $goods_attr;
            if (0 < $store_id) {
                $table_products = 'store_products';
                $where['store_id'] = $store_id;
            } else {
                $table_products = 'products';
            }
            $return_array = \PhalApi\DI()
                    ->notorm
                    ->$table_products
                    ->where($where)
                    ->fetchOne();
        }

        return $return_array;
    }
    private function sort_goods_attr_id_array($goods_attr_id_array, $sort = 'asc') {
        if (empty($goods_attr_id_array)) {
            return $goods_attr_id_array;
        }
        $prefix = \PhalApi\DI()->config->get('dbs.tables.__default__.prefix');
        
        $sql = "select a.attr_type, v.attr_value, v.goods_attr_id, v.attr_checked from " . 
               $prefix."attribute as a left join " .$prefix."goods_attr as v on v.attr_id = a.attr_id and a.attr_type = 1 where v.goods_attr_id " . 
               db_create_in($goods_attr_id_array) . " order by a.sort_order, v.attr_id " . $sort;
        $row = \PhalApi\DI()->notorm->attribute->queryAll($sql, array());
        $return_arr = array();

        foreach ($row as $value) {
            $return_arr['sort'][] = $value['goods_attr_id'];
            $return_arr['row'][$value['goods_attr_id']] = $value;
        }
        
        return $return_arr;
    }
    private function spec_price($spec, $goods_id = 0) {
        $prefix = \PhalApi\DI()->config->get('dbs.tables.__default__.prefix');
        if (!empty($spec)) {
            if (is_array($spec)) {
                foreach ($spec as $key => $val) {
                    $spec[$key] = addslashes($val);
                }
            } else {
                $spec = addslashes($spec);
            }
            if ($this->getConfig('goods_attr_price') == 1) {
                $spec = implode('|', $spec);
                $where['goods_id'] =  $goods_id ;
                
                $table = 'products';
                $where['goods_attr'] =  $spec ;

                $price = \PhalApi\DI()
                    ->notorm
                    ->$table
                    ->select('product_price')
                    ->where($where)
                    ->fetchOne();
                $price = $price['product_price'];
            } else {
                $where = db_create_in($spec, 'goods_attr_id');
                $sql = 'select sum(attr_price) as attr_price from ' .$prefix .'goods_attr where ' . $where .' group by goods_id';
                $price = \PhalApi\DI()->notorm->goods_attr->queryAll($sql, array());
                $price = isset($price[0]['attr_price']) ? $price[0]['attr_price'] : 0;
            }
        } else {
            $price = 0;
        }
        
        return floatval($price);
    }
    
    private function get_goods_attr_info($arr, $type = 'pice') {
        $prefix = \PhalApi\DI()->config->get('dbs.tables.__default__.prefix');
        $attr = '';
        if (!empty($arr)) {
            $fmt = "%s:%s[%s] \n";
            $leftJoin = '';
            $leftJoin .= ' left join ' . $prefix.'goods as g on g.goods_id = ga.goods_id';
            $sql = 'select ga.goods_attr_id, a.attr_name, ga.attr_value,ga.attr_price from ' . 
                   $prefix.'goods_attr as ga ' . $leftJoin . ' left join ' .$prefix.'attribute as a ' . 'on a.attr_id = ga.attr_id ' . 'WHERE ' . db_create_in($arr, 'ga.goods_attr_id');
            $res = \PhalApi\DI()->notorm->goods_attr->queryAll($sql, array());
            $goods_attr_price = $this->getConfig('goods_attr_price');
            foreach ($res as $row) {
                if ($goods_attr_price == 1) {
                    $attr_price = 0;
                } else {
                    $attr_price = round(floatval($row['attr_price']), 2);
                }

                $row['attr_name'] = str_replace('<em>', '', $row['attr_name']);
                $row['attr_name'] = str_replace('</em>', '', $row['attr_name']);
                $attr .= sprintf($fmt, $row['attr_name'], $row['attr_value'], $attr_price);
            }
            
            $attr = str_replace('[0]', '', $attr);
        }
        return $attr;
    }
    
    /**
     * 购物车操作
     * @desc 查看购物车
     * @return int rec_id 购物车ID
     * @return int goods_id 商品ID
     * @return int product_id 规格商品ID
     * @return float goods_price 商品价格
     * @return string goods_attr 规格参数
     * @return int ru_id 店铺ID
     * @return float shipping_fee 运费
     * @return string goods_thumb 商品图片
     * @return string rz_shopName 店铺名
     * @return int stock 库存
     * @return int warn_number 库存预警值
     * @return int total_num 商品总数
     * @return int total_price 商品总价
     */
    public function cartlist() {
        $prefix = \PhalApi\DI()->config->get('dbs.tables.__default__.prefix');
        $userinfo = $this->check_login($this->token);
        $sql = 'select c.rec_id,c.goods_id,c.product_id,c.goods_price,c.goods_number,c.goods_attr,c.goods_attr_id,c.ru_id,c.shipping_fee,g.goods_thumb,m.rz_shopName,g.goods_number as stock,s.rec_id as is_collect,g.goods_name,g.warn_number,g.is_shipping from ' .
               $prefix.'cart as c left join ' .$prefix.'goods as g on c.goods_id = g.goods_id  left join '.
               $prefix.'merchants_shop_information as m on m.user_id = g.user_id  left join '.$prefix.'collect_goods as s on s.goods_id = g.goods_id where c.user_id = '.$userinfo['user_id'].' and c.rec_type = 0 order by c.ru_id asc,c.rec_id desc';
        $data = \PhalApi\DI()->notorm->goods_attr->queryAll($sql, array());
        $list = array();
        if ($data){
            foreach($data as $key=>$vo){
                if ($vo['goods_attr']){
                    $vo['goods_attr'] = strstr($vo['goods_attr'],'[',true);
                }
                if (empty($vo['rz_shopName'])){
                    $vo['rz_shopName'] = '';
                }
                $list[] = $vo;
            }
        }
        return $list;
    }
    /**
     * 购物车操作
     * @desc 更新购物车
     * @return int rec_id 购物车ID
     */
    public function updatecart() {
        $rec_id = $this->rec_id;
        $goods_number = $this->goods_number;
        if(!is_numeric($this->rec_id) || !is_numeric($this->goods_number)){
            $this->api_error_msg('参数错误！');
        }
        $cart = \PhalApi\DI()
                ->notorm
                ->cart
                ->select('product_id,goods_id,goods_number')
                ->where(array('rec_id' => $rec_id))
                ->fetchOne();
        if($goods_number == $cart['goods_number']){
            return false;
        }
        if($cart['product_id'] > 0){
            $product = \PhalApi\DI()
                    ->notorm
                    ->products
                    ->select('product_number')
                    ->where(array('product_id' => $cart['product_id']))
                    ->fetchOne();
            if($product['product_number'] < $goods_number){
                $this->api_error_msg('库存不足！');
            }
        }else{
            $goods = \PhalApi\DI()
                    ->notorm
                    ->goods
                    ->select('goods_number')
                    ->where(array('goods_id' => $cart['goods_id']))
                    ->fetchOne();
            if($goods['goods_number'] < $goods_number){
                $this->api_error_msg('库存不足！');
            }
        }
        
        $update = \PhalApi\DI()->notorm->cart->where('rec_id',$rec_id)->update(array('goods_number'=>$goods_number));
        if($update){
            return true;
        }
        return false;
    }
    /**
     * 购物车操作
     * @desc 删除购物车
     * @return boolean 
     */
    public function delcart() {
        $rec_id = $this->rec_id;
        $rec_id[] = 0;
        $del = \PhalApi\DI()->notorm->cart->where('rec_id', $rec_id)->delete();
        if($del){
            return true;
        }
        return false;
    }

}
